#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
using namespace std;

int g_val = 100;

// int main()
// {
//     pid_t fid = vfork();
//     if(fid == 0)
//     {
//         //child;
//         g_val = 200;
//         cout << "getpid is: " << getpid() << " getppid is: " << getppid() << "g_val is: " << g_val << endl;
//         exit(1);
//     }
//     else if(fid > 0)
//     {
//         sleep(3);
//         cout << "getpid is: " << getpid() << " getppid is: " << getppid() << "g_val is: " << g_val << endl;
//     }
//     return 0;
// }

// #include <stdio.h>
// #include <pthread.h>
// #include <unistd.h>
// void* Routine(void * args)
// {
//     char* mes = (char*) args;
//     while(1)
//     {
//         cout << "i am " << mes << endl;
//         sleep(1);
//     }
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, NULL, Routine, (void*)"thread 1");

//     while(1)
//     {
//         cout << "i am main process!" << endl;
//         sleep(1);
//     }
//     return 0;
// }

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>

// void* Routine(void* arg)
// {
// 	char* msg = (char*)arg;
// 	int count = 5;
// 	while (count--)
//     {
// 		printf("I am %s...pid: %d, ppid: %d, tid: %lu\n", msg, getpid(), getppid(), pthread_self());
// 		sleep(1);
// 	}
// 	return nullptr;
// }

// int main()
// {
// 	pthread_t tid[5];
// 	for (int i = 0; i < 5; i++)
//     {
// 		char* buffer = (char*)malloc(64);
// 		sprintf(buffer, "thread %d", i);
// 		pthread_create(&tid[i], NULL, Routine, buffer);
// 	}
// 	// while (1)
//     // {
// 	// 	printf("I am main thread...pid: %d, ppid: %d\n", getpid(), getppid());
// 	// 	sleep(2);
// 	// }

	
//     for(int i = 0; i < 5; i++)
//     {
// 		void* ret = NULL;
//         pthread_join(tid[i], &ret);
//         printf("thread %d[%lu]...quit, exitcode: %d\n", i, tid[i], (int)ret);
//     }
// 	return 0;
// }

// #include <stdio.h>
// #include <stdlib.h>
// #include <pthread.h>
// #include <unistd.h>
// #include <sys/types.h>

// void* Routine(void* arg)
// {
// 	pthread_detach(pthread_self());
// 	char* msg = (char*)arg;
// 	int count = 0;
// 	while (count < 5)
// 	{
// 		printf("I am %s...pid: %d, ppid: %d, tid: %lu\n", msg, getpid(), getppid(), pthread_self());
// 		sleep(1);
// 		count++;
// 		pthread_cancel(pthread_self());
// 	}
// 	//return (void*)0;
// 	pthread_exit((void*)0);
// }

// int main()
// {
// 	pthread_t tid[5];
// 	for (int i = 0; i < 5; i++)
// 	{
// 		char* buffer = (char*)malloc(64);
// 		sprintf(buffer, "thread %d", i);
// 		pthread_create(&tid[i], NULL, Routine, buffer);
// 		printf("%s tid is %lu\n", buffer, tid[i]);
// 	}
// 	printf("I am main thread...pid: %d, ppid: %d, tid: %lu\n", getpid(), getppid(), pthread_self());
// 	for (int i = 0; i < 5; i++)
// 	{
// 		void* ret = NULL;
// 		pthread_join(tid[i], &ret);
// 		printf("thread %d[%lu]...quit, exitcode: %d\n", i, tid[i], (int)ret);
// 	}
// 	return 0;
// }


// int main()
// {
// 	pthread_t tid[5];
// 	for(int i = 0; i < 5; i++)
// 	{
// 		char* buffer = (char*)malloc(64);
// 		sprintf(buffer, "thread %d", i);
// 		pthread_create(&tid[i], NULL, Routine, buffer);
// 		printf("%s tid is %lu\n", buffer, tid[i]);
// 	}

// 	printf("I am main thread...pid: %d, ppid: %d, tid: %lu\n", getpid(), getppid(), pthread_self());
// 	for (int i = 0; i < 5; i++)
// 	{
// 		void* ret = NULL;
// 		pthread_join(tid[i], &ret);
// 		//printf("thread %d[%lu]...quit, exitcode: %d\n", i, tid[i], (int)ret);
// 	}
// 	return 0;
// }

// void* Routine(void* arg)
// {
// 	while(1)
// 	{
// 		cout << "i am part thread: " << pthread_self() << endl;
// 		sleep(1);
// 	}
// 	return nullptr;
// }

// int main()
// {
// 	pthread_t tid;
// 	pthread_create(&tid, NULL, Routine, NULL);

// 	while(1)
// 	{
// 		cout << "i am main thread: " << pthread_self() << endl;
// 		sleep(1);
// 	}
// 	return 0;
// }

// int count = 0;
// void* Routine(void* arg)
// {
// 	while (1)
// 	{
// 		count++;
// 		sleep(1);
// 	}
// 	pthread_exit((void*)0);
// }

// int main()
// {
// 	pthread_t tid;
// 	pthread_create(&tid, NULL, Routine, NULL);
// 	while (1)
// 	{
// 		printf("count: %d\n", count);
// 		sleep(1);
// 	}
// 	pthread_join(tid, NULL);
// 	return 0;
// }

// #include <stdio.h>
// #include <unistd.h>
// #include <pthread.h>
// pthread_mutex_t mutex;
// int tickets = 1000;

// void* TicketGrabbing(void* arg)
// {
// 	const char* name = (char*)arg;
// 	while (1)
// 	{
// 		pthread_mutex_lock(&mutex);
// 		if (tickets > 0)
// 		{
// 			usleep(10000);
// 			printf("[%s] get a ticket, left: %d\n", name, --tickets);
// 			pthread_mutex_unlock(&mutex);
// 		}
// 		else
// 		{
// 			pthread_mutex_unlock(&mutex);
// 			break;
// 		}
// 	}
// 	printf("%s quit!\n", name);
// 	pthread_exit((void*)0);
// }


// int main()
// {
// 	pthread_mutex_init(&mutex, NULL);
// 	pthread_t t1, t2, t3, t4;
// 	pthread_create(&t1, NULL, TicketGrabbing, (void*)"thread 1");
// 	pthread_create(&t2, NULL, TicketGrabbing, (void*)"thread 2");
// 	pthread_create(&t3, NULL, TicketGrabbing, (void*)"thread 3");
// 	pthread_create(&t4, NULL, TicketGrabbing, (void*)"thread 4");
	
// 	pthread_join(t1, NULL);
// 	pthread_join(t2, NULL);
// 	pthread_join(t3, NULL);
// 	pthread_join(t4, NULL);
// 	pthread_mutex_destroy(&mutex);
// 	return 0;
// }

// pthread_mutex_t mutex;
// void* Routine(void* arg)
// {
// 	pthread_mutex_lock(&mutex);
// 	pthread_mutex_lock(&mutex);
	
// 	pthread_exit((void*)0);
// }

// int main()
// {
// 	pthread_t tid;
// 	pthread_mutex_init(&mutex, NULL);
// 	pthread_create(&tid, NULL, Routine, NULL);
	
// 	pthread_join(tid, NULL);
// 	pthread_mutex_destroy(&mutex);
// 	return 0;
// }

pthread_mutex_t mutex;
pthread_cond_t cond;

void* Routine(void* arg)
{
	pthread_detach(pthread_self());
	std::cout << (char*)arg << " run..." << std::endl;
	while (true)
	{
		pthread_cond_wait(&cond, &mutex); //阻塞在这里，直到被唤醒
		std::cout << (char*)arg << "活动..." << std::endl;
	}
}

int main()
{
	pthread_t t1, t2, t3;
	pthread_mutex_init(&mutex, NULL);
	pthread_cond_init(&cond, NULL);

	pthread_create(&t1, nullptr, Routine, (void*)"thread 1");
	pthread_create(&t2, nullptr, Routine, (void*)"thread 2");
	pthread_create(&t3, nullptr, Routine, (void*)"thread 3");

	while (true)
	{
		getchar();
		pthread_cond_signal(&cond);
	}

	pthread_mutex_destroy(&mutex);
	pthread_cond_destroy(&cond);
	return 0;
}